package me.green.ui;

import java.awt.*;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger;

import javax.swing.*;
import javax.swing.event.HyperlinkEvent;

import me.green.ui.event.EditorPaneLinkEvent;
import me.green.dao.DiaryDao;
import me.green.dao.PlanDao;
import me.green.dao.BywordDao;
import me.green.ui.dialog.DiaryDialog;
import me.green.ui.dialog.FileExportDialog;
import me.green.ui.dialog.PlanDialog;
import me.green.ui.global.UIResources;
import me.green.ui.global.UIStyle;
import me.green.ui.global.i18n.UIText;
import me.green.ui.system.TrayMenu;
import me.green.util.CssStyle;
import me.green.util.DateUtil;
import me.green.util.HtmlBuilder;
import me.green.ui.event.ShortcutKeyListener;

import static javax.swing.SwingConstants.CENTER;

/**
 * 主界面
 *
 * @author green
 */
public class EtnFrame extends JFrame {

    private Logger logger = Logger.getLogger(EtnFrame.class.getName());

    private static final long serialVersionUID = 1L;
    private JPanel panelContent = null;

    private JTabbedPane tabPanel = null;
    private JPanel panelHome = null;
    private JPanel tabPanelDiary;
    private JPanel tabPanelPlan = null;

    private CardLayout diaryTabPanelCardLayout;
    private CardLayout cardLayoutPlan;

    private JPanel panelDiary = null;
    private JPanel panelPlan = null;

    private JLabel labTime = null;
    private JLabel labQuotes = null;
    private JLabel labDiary = null;
    private JLabel labPlan = null;

    private JScrollPane scrollPaneDiary = null;
    private JScrollPane scrollPanePlan = null;

    private JComboBox comDiary = null;
    private JComboBox combPlan = null;

    private JEditorPane editPaneDiary = null;
    private JEditorPane editPanePlan = null;
    private JEditorPane editPaneDiaryDetail = null;

    private JButton btnQuotes = null;
    private JButton btnExport = null;
    private JButton btnBack = null;

    private final int WINDOW_WIDTH = 1200;
    private final int WINDOW_HEIGHT = 940;
    private final int CONTENT_PANEL_WIDTH = WINDOW_WIDTH - 30;
    private final int CONTENT_PANEL_HEIGHT = WINDOW_HEIGHT - 250;

    public enum AreaType {DIARY, PLAN}

    public EtnFrame() {
        initialize();
        startClock();
        this.setVisible(true);
    }

    /**
     * 主选项卡容器
     *
     * @return javax.swing.JTabbedPane
     */
    private JTabbedPane getTabPanel() {
        if (tabPanel == null) {
            tabPanel = new JTabbedPane();
            tabPanel.setFont(UIStyle.defaultFont());
            int tabPanelY = 75;
            int tabPanelHeight = WINDOW_HEIGHT - tabPanelY - 60;
            tabPanel.setBounds(new Rectangle(0, tabPanelY, CONTENT_PANEL_WIDTH, tabPanelHeight));
            tabPanel.addTab(UIStyle.text(UIText.TAB_DIARY), null, getPanelDiary(), null);
            tabPanel.addTab(UIStyle.text(UIText.TAB_PLAN), null, getTabPanelPlan(), null);
            tabPanel.addTab(UIStyle.text(UIText.TAB_HOME), null, getPanelHome(), null);
        }
        return tabPanel;
    }

    /**
     * 主页容器
     *
     * @return javax.swing.JPanel
     */
    private JPanel getPanelHome() {
        if (panelHome == null) {
            panelHome = new JPanel();
            panelHome.setLayout(new FlowLayout(FlowLayout.LEFT));
            panelHome.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 0));

            btnQuotes = new JButton();
            btnQuotes.setToolTipText("设置名言警句");
            btnQuotes.setHorizontalAlignment(CENTER);
            btnQuotes.setFont(UIStyle.defaultFont());
            btnQuotes.setText("名言警句");
            btnQuotes.addMouseListener(new java.awt.event.MouseAdapter() {
                @Override
                public void mouseClicked(java.awt.event.MouseEvent e) {
                    inputQuotes();
                }
            });
            panelHome.add(btnQuotes);
        }
        return panelHome;
    }

    /**
     * 初始化日记容器
     *
     * @return javax.swing.JPanel
     */
    private JPanel getPanelDiary() {
        if (panelDiary == null) {
            labDiary = new JLabel();
            labDiary.setBounds(new Rectangle(15, 10, 58, 54));
            labDiary.setIcon(new ImageIcon(getClass().getResource(UIResources.ICON_DIARY)));
            labDiary.setToolTipText(UIStyle.text(UIText.TIP_WRITE_DIARY));
            labDiary.setText("");

            labDiary.addMouseListener(new java.awt.event.MouseAdapter() {
                @Override
                public void mouseClicked(java.awt.event.MouseEvent e) {
                    logger.info("click add diary");
                    new DiaryDialog(EtnFrame.this, true);
                }
            });
            labDiary.addMouseListener(new java.awt.event.MouseAdapter() {
                @Override
                public void mouseEntered(java.awt.event.MouseEvent e) {
                    labDiary.setIcon(new ImageIcon(getClass().getResource(
                            UIResources.ICON_DIARY_ON)));
                }

                @Override
                public void mouseExited(java.awt.event.MouseEvent e) {
                    labDiary.setIcon(new ImageIcon(getClass().getResource(
                            UIResources.ICON_DIARY)));
                }
            });
            panelDiary = new JPanel();
            panelDiary.setLayout(null);
            panelDiary.add(labDiary, null);
            panelDiary.add(getBtnBack(), null);
            panelDiary.add(getCombDiary(), null);

            scrollPaneDiary = new JScrollPane(geTabPanelDiary());
            scrollPaneDiary.setBounds(new Rectangle(0, 82, CONTENT_PANEL_WIDTH - 3, CONTENT_PANEL_HEIGHT));
            panelDiary.add(scrollPaneDiary, null);
        }
        return panelDiary;
    }


    private JPanel geTabPanelDiary() {
        if (null == tabPanelDiary) {
            diaryTabPanelCardLayout = new CardLayout();
            tabPanelDiary = new JPanel(diaryTabPanelCardLayout);
            tabPanelDiary.add(initDiaryEditorPane(), "list");
            tabPanelDiary.add(initDiaryDetailEditorPane(), "detail");
        }
        return tabPanelDiary;
    }

    private JEditorPane initDiaryEditorPane() {
        if (editPaneDiary == null) {
            editPaneDiary = new JEditorPane();
            editPaneDiary.setContentType("text/html");
            editPaneDiary.setEditable(false);
            editPaneDiary.setEditorKit(CssStyle.defaultItemCssStyle());
            editPaneDiary.addHyperlinkListener(new javax.swing.event.HyperlinkListener() {
                @Override
                public void hyperlinkUpdate(javax.swing.event.HyperlinkEvent e) {
                    logger.info("diary link event type: " + e.getEventType() + ", desc:" + e.getDescription());
                    if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
                        if (e.getDescription() == null || e.getDescription().equals("")) {
                            return;
                        } else {
                            // 显示详情
                            btnBack.setVisible(true);
                            JEditorPane editorPane = initDiaryDetailEditorPane();
                            new EditorPaneLinkEvent(e.getDescription(), editorPane, EditorPaneLinkEvent.METHOD_DIARY);
                            diaryTabPanelCardLayout.show(geTabPanelDiary(), "detail");
                        }
                    }
                }
            });
            // 显示列表
            java.sql.Date weekBefore = (java.sql.Date) DateUtil.getWeekBegin(0);
            java.sql.Date weekEnd = (java.sql.Date) DateUtil.getWeekEnd(weekBefore);
            displayEditorPane(weekBefore, weekEnd, editPaneDiary, AreaType.DIARY);
        }
        return editPaneDiary;
    }


    private JEditorPane initDiaryDetailEditorPane() {
        if (editPaneDiaryDetail == null) {
            editPaneDiaryDetail = new JEditorPane();
            editPaneDiaryDetail.setContentType("text/html");
            editPaneDiaryDetail.setEditable(false);
            editPaneDiaryDetail.setEditorKit(CssStyle.defaultItemCssStyle());
            editPaneDiaryDetail.setSelectionColor(new Color(7, 193, 96));
            editPaneDiaryDetail.setSelectedTextColor(Color.WHITE);
        }
        return editPaneDiaryDetail;
    }


    /**
     * 初始化计划容器
     *
     * @return javax.swing.JPanel
     */
    private JPanel getTabPanelPlan() {
        if (tabPanelPlan == null) {
            cardLayoutPlan = new CardLayout();
            tabPanelPlan = new JPanel(cardLayoutPlan);
            tabPanelPlan.add(intPlanPanel(), "list");
            tabPanelPlan.setBounds(new Rectangle(0, 82, CONTENT_PANEL_WIDTH - 3, CONTENT_PANEL_HEIGHT));
        }
        return tabPanelPlan;
    }


    private JPanel intPlanPanel() {
        if (panelPlan == null) {
            labPlan = new JLabel();
            labPlan.setBounds(new Rectangle(15, 10, 58, 54));
            labPlan.setIcon(new ImageIcon(getClass().getResource(UIResources.ICON_PLAN)));
            labPlan.setHorizontalAlignment(CENTER);
            labPlan.setToolTipText("添加计划");
            labPlan.setText("");
            labPlan.setCursor(new Cursor(Cursor.HAND_CURSOR));
            labPlan.addMouseListener(new java.awt.event.MouseAdapter() {
                @Override
                public void mouseClicked(java.awt.event.MouseEvent e) {
                    new PlanDialog(EtnFrame.this, true);
                }

                @Override
                public void mouseEntered(java.awt.event.MouseEvent e) {
                    labPlan.setIcon(new ImageIcon(getClass().getResource(
                            UIResources.ICON_PLAN_ON)));
                }

                @Override
                public void mouseExited(java.awt.event.MouseEvent e) {
                    labPlan.setIcon(new ImageIcon(getClass().getResource(
                            UIResources.ICON_PLAN)));
                }
            });

            panelPlan = new JPanel();
            panelPlan.setLayout(null);
            panelPlan.add(labPlan, null);
            panelPlan.add(getScrollPanePlan(), null);
            panelPlan.add(getCombPlan(), null);
        }
        return panelPlan;
    }


    /**
     * 计划滚动容器初始化
     *
     * @return javax.swing.JScrollPane
     */
    private JScrollPane getScrollPanePlan() {
        if (scrollPanePlan == null) {
            scrollPanePlan = new JScrollPane();
            scrollPanePlan.setBounds(new Rectangle(1, 82, WINDOW_WIDTH - 10, WINDOW_HEIGHT - 82 - 5));
            scrollPanePlan.setViewportView(getEditPanePlan());
        }
        return scrollPanePlan;
    }

    /**
     * This method initializes combCondition
     *
     * @return javax.swing.JComboBox
     */
    private JComboBox getCombDiary() {
        if (comDiary == null) {
            comDiary = new JComboBox();
            int combWidth = 154;
            int x = WINDOW_WIDTH - combWidth - 40;
            comDiary.setBounds(new Rectangle(x, 28, combWidth, 32));
            comDiary.setFont(UIStyle.defaultFont());
            comDiary.addItem("本周");
            comDiary.addItem("上周");
            comDiary.addItem("显示全部");

            comDiary.addActionListener(new java.awt.event.ActionListener() {
                @Override
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    updateEditorPaneContent();
                }
            });
        }
        return comDiary;
    }


    /**
     * This method initializes editPanePlan
     *
     * @return javax.swing.JEditorPane
     */
    private JEditorPane getEditPanePlan() {
        if (editPanePlan == null) {
            editPanePlan = new JEditorPane();
            editPanePlan.setContentType("text/html");
            editPanePlan.setEditable(false);

            java.sql.Date weekBefore = (java.sql.Date) DateUtil.getWeekBegin(0);
            java.sql.Date weekEnd = (java.sql.Date) DateUtil.getWeekEnd(weekBefore);
            editPanePlan.setEditorKit(CssStyle.defaultItemCssStyle());
            editPanePlan.addHyperlinkListener(new javax.swing.event.HyperlinkListener() {
                @Override
                public void hyperlinkUpdate(javax.swing.event.HyperlinkEvent e) {
                    if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
                        if (e.getDescription() == null || e.getDescription().equals("")) {
                            return;
                        } else {
                            new EditorPaneLinkEvent(e.getDescription(), editPanePlan, EditorPaneLinkEvent.METHOD_PLAN);
                        }

                    }
                }
            });
            displayEditorPane(weekBefore, weekEnd, editPanePlan, AreaType.PLAN);

        }
        return editPanePlan;
    }


    /**
     * This method initializes this
     *
     * @return void
     */
    private void initialize() {
        this.setSize(new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT));
        this.setResizable(false);
        this.setContentPane(getPanelContent());
        this.setTitle(UIStyle.text(UIText.TITLE));
        this.setIconImage(new ImageIcon(this.getClass().getResource(UIResources.ICON_TRAY)).getImage());
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.addWindowListener(new java.awt.event.WindowAdapter() {
            @Override
            public void windowIconified(java.awt.event.WindowEvent e) {
                EtnFrame.this.setState(JFrame.ICONIFIED);
                EtnFrame.this.setVisible(false);
                EtnFrame.this.setAlwaysOnTop(false);
                TrayMenu sysTray = TrayMenu.getInstances(EtnFrame.this);
                LocalCache.setSysTray(sysTray);
                if (LocalCache.isLock()) {
                    sysTray.lock();
                }

            }
        });
        this.setLocationRelativeTo(this);
        // 注册全局快捷键
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        toolkit.addAWTEventListener(ShortcutKeyListener.getInstance(this), AWTEvent.KEY_EVENT_MASK);
    }

    /**
     * This method initializes jContentPane
     *
     * @return javax.swing.JPanel
     */
    private JPanel getPanelContent() {
        if (panelContent == null) {
            labTime = new JLabel();
            int labTimeWidth = 195;
            labTime.setBounds(new Rectangle(WINDOW_WIDTH - labTimeWidth - 30, 15, labTimeWidth, 32));
            labTime.setFont(UIStyle.defaultFont());
            // 文字居中展示
            labTime.setHorizontalAlignment(CENTER);
            labTime.setText("");

            // 名言警句
            labQuotes = new JLabel();
            labQuotes.setBounds(new Rectangle(15, 15, WINDOW_WIDTH - labTimeWidth - 50, 48));
            labQuotes.setFont(UIStyle.titleFont());
            labQuotes.setText(new BywordDao().getUserByword(LocalCache.getUser().getId()));
            labQuotes.setForeground(new Color(89, 89, 89));

            panelContent = new JPanel();
            panelContent.setLayout(null);
            panelContent.add(getTabPanel());
            panelContent.add(labQuotes);
            panelContent.add(labTime);
        }
        return panelContent;
    }

    public void displayEditorPane(java.sql.Date weekBefore, java.sql.Date weekEnd, JEditorPane editor, AreaType type) {
        List list = null;
        switch (type) {
            case DIARY:
                list = new DiaryDao().queryDiary(LocalCache.getUser().getId(), weekBefore, weekEnd);
                editor.setText(HtmlBuilder.genDiariesHtmlString(list));
                break;
            case PLAN:
                list = new PlanDao().getPlanByWeek(LocalCache.getUser().getId(), weekBefore, weekEnd);
                editor.setText(HtmlBuilder.genPlansHtmlString(list));
                break;
        }
    }

    public void displayAll(JEditorPane editor, AreaType type) {
        List list = null;
        switch (type) {
            case DIARY:
                list = new DiaryDao().queryAllDiary(LocalCache.getUser().getId());
                editor.setText(HtmlBuilder.genDiariesHtmlString(list));
                break;
            case PLAN:
                list = new PlanDao().getAllUserPlans(LocalCache.getUser().getId());
                editor.setText(HtmlBuilder.genPlansHtmlString(list));
                break;
        }
    }

    /**
     * This method initializes combCondition2
     *
     * @return javax.swing.JComboBox
     */
    private JComboBox getCombPlan() {
        if (combPlan == null) {
            combPlan = new JComboBox();
            int combWidth = 154;
            combPlan.setBounds(new Rectangle(WINDOW_WIDTH - combWidth - 40, 28, combWidth, 32));
            combPlan.setFont(UIStyle.defaultFont());
            combPlan.addItem("本周");
            combPlan.addItem("下周");
            combPlan.addItem("显示全部");
            combPlan.addActionListener(new java.awt.event.ActionListener() {
                @Override
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    updateEditorPaneContent();
                }
            });
        }
        return combPlan;
    }

    /**
     * 时钟开始
     */
    private void startClock() {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new DateTimer(), new Date(), 1000);
    }

    /**
     * 更新容器内容
     */
    public void updateEditorPaneContent() {
        if (comDiary.getSelectedItem().toString().equals("本周")) {
            java.sql.Date beginDate = new java.sql.Date(DateUtil.getWeekBegin(0).getTime());
            displayEditorPane(beginDate, new java.sql.Date(DateUtil.getWeekEnd(beginDate).getTime()),
                    editPaneDiary, AreaType.DIARY);
        }

        if (comDiary.getSelectedItem().toString().equals("上周")) {
            java.sql.Date beginDate = new java.sql.Date(DateUtil.getWeekBegin(-1).getTime());
            displayEditorPane(beginDate, new java.sql.Date(DateUtil.getWeekEnd(
                    beginDate).getTime()), editPaneDiary,
                    AreaType.DIARY);
        }
        if (comDiary.getSelectedItem().toString().equals("显示全部")) {
            displayAll(editPaneDiary, AreaType.DIARY);
        }

        if (combPlan.getSelectedItem().toString().equals("本周")) {
            java.sql.Date weekBegin = (java.sql.Date) DateUtil.getWeekBegin(0);
            displayEditorPane(weekBegin, new java.sql.Date(DateUtil.getWeekEnd(weekBegin).getTime()),
                    editPanePlan, AreaType.PLAN);
        }
        if (combPlan.getSelectedItem().toString().equals("显示全部")) {
            displayAll(editPanePlan, AreaType.PLAN);
        }
        if (combPlan.getSelectedItem().toString().equals("下周")) {
            java.sql.Date begin = new java.sql.Date(DateUtil.getWeekBegin(1).getTime());
            displayEditorPane(begin, (java.sql.Date) DateUtil.getWeekEnd(begin),
                    editPanePlan, AreaType.PLAN);
        }
    }

    private void inputQuotes() {
        UIManager.put("OptionPane.messageFont", UIStyle.defaultFont());
        UIManager.put("OptionPane.buttonFont", UIStyle.defaultFont());
        String words = JOptionPane.showInputDialog(EtnFrame.this,
                UIStyle.text(UIText.TIP_INPUT_QUOTES));
        if (words == null || words.trim().equals("")) {
            return;
        }
        boolean flag = new BywordDao().saveUserByword(LocalCache.getUser().getId(), words.trim());
        if (flag) {
            JOptionPane.showMessageDialog(EtnFrame.this, UIStyle.text(UIText.SUCCESS_SAVE));
            labQuotes.setText(words);
        } else {
            JOptionPane.showMessageDialog(EtnFrame.this, UIStyle.text(UIText.ERROR_SAVE));
        }
    }

    class DateTimer extends TimerTask {
        @Override
        public void run() {
            labTime.setText(DateUtil.currentDateTime());
        }
    }

    /**
     * 返回按钮
     *
     * @return javax.swing.JButton
     */
    private JButton getBtnBack() {
        if (btnBack == null) {
            btnBack = new JButton();
            btnBack.setVisible(false);
            btnBack.setText("返回");
            btnBack.setFont(UIStyle.defaultFont());
            int btnBackWidth = 90;
            btnBack.setBounds(new Rectangle(getCombDiary().getX() - btnBackWidth - 20, 27, btnBackWidth, 32));
            btnBack.addActionListener(new java.awt.event.ActionListener() {
                @Override
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    logger.info("click back button");
                    diaryTabPanelCardLayout.show(geTabPanelDiary(), "list");
                    btnBack.setVisible(false);
                    JScrollBar scrollBar = scrollPaneDiary.getVerticalScrollBar();
                    logger.info("scroll value:" + scrollBar.getValue());
                }
            });
        }
        return btnBack;
    }


    /**
     * 导出按钮
     *
     * @return javax.swing.JButton
     */
    private JButton getBtnExport() {
        if (btnExport == null) {
            btnExport = new JButton();
            btnExport.setText("导出");
            btnExport.setBounds(new Rectangle(403, 27, 91, 32));
            btnExport.addActionListener(new java.awt.event.ActionListener() {
                @Override
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    new FileExportDialog(EtnFrame.this, true, FileExportDialog.EXPORT_DIARY);
                }
            });
        }
        return btnExport;
    }

}
